package sketch.ink;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

import sketch.doc.Sketch;
import sketch.shape.geom.prim.Point;

public class Stroke {

	private List<SampledPoint> points;

	private int originalStrokeId;

//	private List<Stroke> subStrokes;

//	private CornerDetector cd;

	private boolean used = false;

	private List<SampledPoint> corners;

	public boolean isUsed() {
		return used;
	}

	public void setUsed(boolean b) {
		used = b;
	}

//	public CornerDetector getCD() {
//		return cd;
//	}

	private int id;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Stroke() {
		points = new ArrayList<SampledPoint>();
		corners = new ArrayList<SampledPoint>();
//		setId(Sketch.generateId());
//		cd = new CDStaticKH(this);
//		setCDType(CDFactory.TYPE.StaticKH);
		originalStrokeId = -1;
	}

//	public void setCDType(CDFactory.TYPE type) {
//		cd = CDFactory.getCD(type);
//		cd.setHost(this);
//	}

	public boolean appendPoint(SampledPoint sp) {
		return points.add(sp);
	}

	public List<SampledPoint> getPoints() {
		return points;
	}

	public void setPoints(List<SampledPoint> ps) {
		points = ps;
	}

	public List<SampledPoint> getCorners() {
		return corners;
	}

	public void setCorners(List<SampledPoint> cs) {
		corners = cs;
	}

	public int length() {
		return points.size();
	}

	public SampledPoint getPoint(int i) {
		return points.get(i);
	}

	public void draw(Graphics2D g2) {
		draw(g2, Color.BLACK, 2);
	}

	public void draw(Graphics2D g2, Color color, int width) {
		if (length() <= 1)
			return;

		g2.setColor(color);
		g2.setStroke(new BasicStroke(width));

		SampledPoint p1 = getPoint(0);
		for (int i = 1; i < length(); i++) {
			SampledPoint p2 = getPoint(i);
			g2.drawLine((int) p1.getX(), (int) p1.getY(),
						(int) p2.getX(), (int) p2.getY());
			p1 = p2;
		}
	}

	public int getOriginal() {
		return (originalStrokeId == -1) ? getId() : originalStrokeId;
	}

	public void setOriginal(int id) {
		originalStrokeId = id;
	}

	public void drawSelected(Graphics2D g2) {

//		List<SampledPoint> corners = getCD().getCorners();

    	g2.setColor(Color.RED);
		g2.setStroke(new BasicStroke(3));

    	for (SampledPoint pp : getCorners()) {
    		Point p = pp.toPoint();
    		g2.drawOval(p.intX()-3, p.intY()-3, 6, 6);
    	}

    	draw(g2, Color.BLUE, 2);
	}

//	public void setCD(CornerDetector cd) {
//		this.cd = cd;
//		this.cd.setHost(this);
//	}

	public String toSimpleML() {
		StringBuffer buf = new StringBuffer();
		buf.append("Stroke:");
		buf.append(getId());
		buf.append(":");
		for (SampledPoint point : getPoints()) {
			buf.append(point.toSimpleML());
		}
		return buf.toString();
	}

	public static Stroke parseSimpleML(String string) {
		String[] parts = string.split(":");

		if (parts.length != 3)
			return null;

		Stroke stroke = new Stroke();
		stroke.setId(Integer.parseInt(parts[1]));

		String seq = parts[2];
		int state = 0; // 0 : before (
		               // 1 : between ( and )
		int prev = 0;
		for (int i = 0; i < seq.length(); i++) {
			if (seq.charAt(i) == '(' && state == 0) {
				state = 1;
				prev = i;
			} else if (seq.charAt(i) == ')' && state == 1) {
				state = 0;
				stroke.appendPoint(SampledPoint.parseSimpleML((seq.substring(prev, i+1))));
			}
		}

		return stroke;
	}

	public Point getCenter() {
		double x = 0, y = 0;
		for (SampledPoint p : getPoints()) {
			x += p.getX();
			y += p.getY();
		}
		return new Point(x/getPoints().size(), y/getPoints().size());
	}

	public void move(Point vector) {
		List<SampledPoint> ps = new ArrayList<SampledPoint>();
		for (SampledPoint p : getPoints()) {
			ps.add(p.add(vector));
		}
		setPoints(ps);

		ps = new ArrayList<SampledPoint>();
		for (SampledPoint p : getCorners()) {
			ps.add(p.add(vector));
		}
		setCorners(ps);
	}



}
